package example.documentbased.mainModule.services.mocks
{
	import example.documentbased.mainModule.models.doman.Document;
	import example.documentbased.mainModule.models.factories.ItemsFactory;
	import example.documentbased.mainModule.services.IDocumentService;
	
	import mx.utils.UIDUtil;
	
	import org.etherframework.common.utils.OU;
	
	import raix.reactive.IObservable;
	import raix.reactive.Observable;
	import raix.reactive.Unit;
	
	public class DocumentServiceMock implements IDocumentService
	{
		private var _model:ServiceMockModel;
		private var _itemsFactory:ItemsFactory;
		
		public function DocumentServiceMock(model:ServiceMockModel, itemsFactory:ItemsFactory)
		{
			_model = model;
			_itemsFactory = itemsFactory;
		}
		
		public function saveDocument(document:Document):IObservable
		{
			var doc:Document;
			var id:String;
			
			if (document.id)
			{
				id = document.id;
				doc = getDocumentById(document.id);
				// if doc == null should handle exception here
				doc.id = document.id;
				doc.editorId = document.editorId;
				doc.name = document.name;
				
				if (doc.lazy)
				{
					_model.setContent(doc, document.text);
				}
				else
				{
					doc.text = document.text;
				}
			}
			else
			{
				id = UIDUtil.createUID();
				doc = _itemsFactory.createDocument(id, document.uid, 
					document.editorId, document.name, document.text);
				_model.documents.push(doc);
			}
			
			return Observable.defer(function():IObservable 
			{
				return Observable.value(id);
			}).delay(1000);
		}
		
		private function getDocumentById(id:String):Document
		{
			const docs:Vector.<Document> = _model.documents;
			
			for (var i:int = 0; i < docs.length; i++) 
			{
				if (docs[i].id == id)
				{
					return docs[i];
				}
			}
			return null;
		}
		
		public function getDocuments(editorId:String):IObservable
		{
			var result:Vector.<Document> = new Vector.<Document>();
			var documents:Vector.<Document> = _model.documents;
			
			for (var i:int = 0; i < documents.length; i++) 
			{
				if (documents[i].editorId == editorId)
				{
					result.push(documents[i]);
				}
			}
			
			return Observable.defer(function():IObservable 
			{
				return Observable.value(result);
			}).delay(500);
		}
		
		public function deleteDocument(document:Document):IObservable
		{
			var doc:Document = OU.getItem(_model.documents, "id", document.id);
			
			if (doc)
			{
				_model.documents.splice(_model.documents.indexOf(doc), 1);
			}
			else
			{
				return Observable.error(new Error("Can not delete document. Document with id="+
					document.id + " does not exist."));
			}
			
			return Observable.defer(function():IObservable 
			{
				return Observable.value(new Unit());
			}).delay(500);
		}
		
		public function getDocumentContent(document:Document):IObservable
		{
			return Observable.defer(function():IObservable {
				return Observable.value(_model.getContent(document));
			}).delay(700);
		}
	}
}